﻿using AutoControlSpectrum.Manufacturer;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace AutoControlSpectrum.Device
{
    internal class SocketServer
    {
        private static readonly SocketServer instance = new SocketServer();

        /// <summary>
        /// 私有构造函数，防止实例化
        /// </summary>
        private SocketServer() => SetupServer();

        /// <summary>
        ///  公共静态方法，返回唯一的实例
        /// </summary>
        public static SocketServer Instance => instance;

        /// <summary>
        /// socket启动端口
        /// </summary>
        private const int PROT = 776;

        /// <summary>
        /// 消息回调
        /// </summary>
        public Action<string> MsgCallback = (a) => { };

        /// <summary>
        /// 所有连接的客户端
        /// </summary>
        private List<Socket> clientSockets = new List<Socket>();

        /// <summary>
        /// socket服务
        /// </summary>
        private Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        /// <summary>
        /// 缓冲器大小
        /// </summary>
        private const int BUFFER_SIZE = 2048;

        /// <summary>
        /// 缓冲区
        /// </summary>
        private readonly byte[] buffer = new byte[BUFFER_SIZE];

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="port">启动端口</param>
        public void SetupServer()
        {
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, PROT));
            //serverSocket.Bind(new IPEndPoint(IPAddress.Parse("100.96.143.46"), PROT));
            serverSocket.Listen(5);
            serverSocket.BeginAccept(AcceptCallback, null);

            Task.Run(() =>
            {
                Task.Delay(1000);
                MsgCallback($"SocketServer服务已启动，端口：{PROT}");
            });
        }

        /// <summary>
        /// 等待连接
        /// </summary>
        /// <param name="AR"></param>
        public void AcceptCallback(IAsyncResult AR)
        {
            Socket socket = serverSocket.EndAccept(AR);
            clientSockets.Add(socket);
            MsgCallback($"{DateTime.Now:MM-dd HH:mm:ss}，客户端连接");
            socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
            serverSocket.BeginAccept(AcceptCallback, null);
            DeviceControl.Instance.initialized = false;
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="AR"></param>
        public void ReceiveCallback(IAsyncResult AR)
        {
            Socket current = (Socket)AR.AsyncState;
            int received;

            try
            {
                received = current.EndReceive(AR);
            }
            catch (SocketException)
            {
                MsgCallback($"{DateTime.Now:MM-dd HH:mm:ss}，客户端被强行断开");
                current.Close();
                clientSockets.Remove(current);
                return;
            }

            byte[] recBuf = new byte[received];
            Array.Copy(buffer, recBuf, received);
            string text = Encoding.UTF8.GetString(recBuf);
            MsgCallback(text);

            current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
        }

        /// <summary>
        /// 发送消息给所有客户端
        /// </summary>
        /// <param name="message">消息内容</param>
        public void SendToAllClients(string message)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            foreach (Socket client in clientSockets)
            {
                client.Send(data);
            }
        }
    }
}